package com.jxd.project.travel.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jxd.project.travel.dao.ITicketDao;
import com.jxd.project.travel.model.FileConfig;
import com.jxd.project.travel.model.Ticket;
import com.jxd.project.travel.service.ITicketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;

import java.io.File;
import java.net.URL;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName TicketServiceImpl
 * @Description TODO
 * @Author 邢子剑
 * @Date 2025/9/24 上午8:58
 * @Version 1.0
 */
@Service
public class TicketServiceImpl extends ServiceImpl<ITicketDao, Ticket> implements ITicketService {

    @Autowired
    private ITicketDao ticketDao;

    @Autowired
    private FileConfig fileConfig;

    @Override
    public IPage<Ticket> getTicketList(int pageNum, int pageSize, String departure, String arrival, int empno) {
        IPage<Ticket> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Ticket> queryWrapper = new QueryWrapper<>();
        if (departure != null && !departure.isEmpty()) {
            queryWrapper.like("departure", departure);
        }
        if (arrival != null && !arrival.isEmpty()) {
            queryWrapper.like("arrival", arrival);
        }
        if (empno != 0) {
            queryWrapper.eq("empno", empno);
        }
        return ticketDao.selectPage(page, queryWrapper);
    }

    @Override
    public boolean insertTicket(Ticket ticket) {
        return ticketDao.insert(ticket) > 0;
    }

    @Override
    public boolean updateTicket(Ticket ticket) {
        LambdaQueryWrapper<Ticket> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Ticket::getTicketId, ticket.getTicketId());
        String travelId = ticketDao.selectOne(queryWrapper).getTravelId();
        if (travelId == null || travelId.equals("0")) {//判断是否绑定差旅信息
            return ticketDao.updateById(ticket) > 0;
        } else {
            return false;
        }
    }

    @Override
    public boolean deleteTicket(int ticketId) {
        LambdaQueryWrapper<Ticket> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Ticket::getTicketId, ticketId);
        String travelId = ticketDao.selectOne(queryWrapper).getTravelId();
        if (travelId.isEmpty()) {//判断是否绑定差旅信息
            return ticketDao.deleteById(ticketId) > 0;
        } else {
            return false;
        }
    }

    /**
     * 批量删除票据信息
     * @param ticketIds
     * @return
     */
    @Override
    public boolean deleteTicketBatch(List<Integer> ticketIds) {
        boolean flag = true;
        for (int ticketId : ticketIds) {
            LambdaQueryWrapper<Ticket> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Ticket::getTicketId, ticketId);
            Ticket ticket = ticketDao.selectOne(queryWrapper);
            if (ticket.getTravelId() != null && !ticket.getTravelId().equals("0")) { // 判断是否绑定差旅信息
                flag = false;
                break; // 如果发现有绑定差旅信息的，直接跳出循环
            }
        }
        if (flag) {
            return ticketDao.deleteBatchIds(ticketIds) > 0; // 批量删除
        } else {
            return false; // 如果有绑定差旅信息的，则返回 false
        }
    }

    // 后端批量删除图片接口示例
    @PostMapping("/deleteTicketImagesBatch")
    public boolean deleteImageByUrl(String imageUrl) {
        try {
            // 1. 解析URL，获取路径部分（如：/upload/ticket/xxx.jpg）
            URL url = new URL(imageUrl);
            String urlPath = url.getPath();

            // 2. 转换为服务器实际存储路径（去掉accessPath前缀）
            // 例如：accessPath=/upload/** → 截取后为ticket/xxx.jpg
            String relativePath = urlPath.replace(fileConfig.getAccessPath().replace("**", ""), "");
            String realFilePath = fileConfig.getUploadPath() + relativePath;

            // 3. 执行删除
            File imageFile = new File(realFilePath);
            if (imageFile.exists() && imageFile.isFile()) {
                return imageFile.delete();
            } else {
                // 文件不存在，视为“删除成功”（避免阻塞后续操作）
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 查询未绑定车票和该差旅已绑定车票
     * @param empno
     * @param travelId
     * @return
     */
    @Override
    public List<Ticket> getTicketByEmpno(Integer empno, String travelId) {
        QueryWrapper<Ticket> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("empno", empno)
                .and(wrapper -> wrapper
                        .eq("travelId", travelId)
                        .or()
                        .isNull("travelId")
                        .or()
                        .eq("travelId", 0)
                )
                .orderBy(true, true, "startTime");

        return ticketDao.selectList(queryWrapper);
    }

    /**
     * 删除差旅信息时，只删除关联的票据信息中的差旅编号信息，不删除票据信息本身
     * @param travelIds
     * @return
     */
    @Override
    public boolean deleteTravelIdInTicket(List<String> travelIds) {
        // 创建更新条件包装器
        LambdaUpdateWrapper<Ticket> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(Ticket::getTravelId, travelIds)
                .set(Ticket::getTravelId, 0);

        // 执行更新
        int affectedRows = ticketDao.update(null, updateWrapper);

        return affectedRows > 0;
    }

    /**
     * 计算差旅车票总价格
     * @param ticketIds
     * @return
     */
    @Override
    public double getAllTicketPrice(int[] ticketIds) {
        double sum = 0;
        for (int ticketId : ticketIds) {
            Ticket ticket = ticketDao.selectById(ticketId);
            sum += ticket.getPrice();
        }
        return sum;
    }

    /**
     * 重置差旅信息
     * @param travelId
     * @return
     */
    @Override
    public boolean resetTravelIdInTicket(String travelId) {
        LambdaUpdateWrapper<Ticket> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Ticket::getTravelId, travelId);
        updateWrapper.set(Ticket::getTravelId, 0);
        return ticketDao.update(null, updateWrapper) > 0;
    }

    /**
     * 绑定差旅信息
     * @param travelId
     * @param ticketIds
     * @return
     */
    @Override
    public List<Ticket> setTravelId(String travelId, int[] ticketIds) {
        List<Ticket> tickets = new ArrayList<>();
        for (int ticketId : ticketIds) {
            Ticket ticket = ticketDao.selectById(ticketId);
            ticket.setTravelId(travelId);
            ticketDao.updateById(ticket);
            tickets.add(ticket);
        }
        return tickets;
    }

    /**
     * 计算差旅时长
     * @param tickets
     * @return
     */
    @Override
    public double getTravelTime(List<Ticket> tickets) {
        double travelDays = 0;
        String startTime = tickets.get(0).getStartTime();
        String endTime = tickets.get(tickets.size()-1).getEndTime();
        double firstDay = 0;
        double lastDay = 0;
        double midDays = 0;

        if (Integer.parseInt(startTime.substring(11,13)) < 12) {
            firstDay = 1;
        } else {
            firstDay = 0.5;
        }

        if (Integer.parseInt(endTime.substring(11,13)) < 12) {
            lastDay = 0.5;
        } else {
            lastDay = 1;
        }

        // 定义时间格式器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 解析字符串为LocalDateTime
        LocalDateTime dateTime1 = LocalDateTime.parse(startTime, formatter);
        LocalDateTime dateTime2 = LocalDateTime.parse(endTime, formatter);

        // 提取日期部分（忽略时分秒）
        LocalDate date1 = dateTime1.toLocalDate();
        LocalDate date2 = dateTime2.toLocalDate();

        // 计算天数差（结果可为正/负，取决于两个日期的先后）
        long daysDiff = ChronoUnit.DAYS.between(date1, date2);
        midDays = Math.abs(daysDiff) - 1; // 取绝对值，避免负数
        if(midDays < 0) midDays = 0;      // 防止差一天时 midDays 为 -1


        travelDays = firstDay + midDays + lastDay;
        return travelDays;
    }

    @Override
    public Ticket getOne(int ticketId) {
        return ticketDao.selectById(ticketId);
    }

    @Override
    public Ticket getLastTicket(int empno) {
        LambdaQueryWrapper<Ticket> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Ticket::getEmpno, empno);
        queryWrapper.orderByDesc(Ticket::getTicketId).last("limit 1");
        return ticketDao.selectOne(queryWrapper);
    }
}
